package hu.bme.mit.rifl.gui;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

/**
 * Base class for the GUI of the worker nodes. It draws a Swing window
 * containing a label for counting calls and a button to process the next work
 * item (Order). The window also contains a checkbox to automatize the function
 * of the button and an area to display logs.
 */
public class WFElementGUI extends JFrame {
	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	private JLabel callCountLabel;
	private JButton workButton;
	private JCheckBox autoCheckbox;
	private JTextArea logTextArea;

	private int callCount;
	private boolean buttonClicked;
	private boolean closed = false;

	/**
	 * Getter for the button "state".
	 * 
	 * @return true if the next work item should be processed
	 */
	public boolean isButtonClicked() {
		boolean ret = autoCheckbox.isSelected() || buttonClicked;
		buttonClicked = false;
		return ret;
	}

	public boolean isClosed() {
		return closed;
	}

	/**
	 * Setter for the checkbox.
	 * 
	 * @param b
	 *            the new state of the checkbox
	 */
	public void setAutoSelected(Boolean b) {
		autoCheckbox.setSelected(b);
	}

	/**
	 * Clears the content of the log area.
	 */
	public void clearLog() {
		logTextArea.setText("");
	}

	/**
	 * Create the frame.
	 */
	public WFElementGUI(String title) {
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setBounds(0, 0, 300, 200);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

		JPanel panel = new JPanel();
		contentPane.add(panel);

		workButton = new JButton();
		workButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				buttonClicked = true;
			}
		});
		panel.setLayout(new GridLayout(0, 3, 10, 0));

		callCountLabel = new JLabel();
		callCountLabel.setHorizontalAlignment(SwingConstants.TRAILING);
		panel.add(callCountLabel);
		panel.add(workButton);

		autoCheckbox = new JCheckBox("auto");
		panel.add(autoCheckbox);

		logTextArea = new JTextArea();
		logTextArea.setEditable(false);
		logTextArea.setText("log");
		contentPane.add(logTextArea);
		initialize(title);
	}

	/**
	 * Initialize GUI elements' state.
	 * 
	 * @param title
	 *            title for the Swing window
	 */
	private void initialize(String title) {
		setTitle(title);
		callCount = 0;
		buttonClicked = false;
		callCountLabel.setText(Integer.toString(callCount));
		workButton.setText("WORK");
		autoCheckbox.setSelected(false);
		logTextArea.setText("");
		applyLocation();

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				closed = true;
			}
		});
	}

	/**
	 * Sets the position of GUI windows.
	 */
	private void applyLocation() {
		if (getTitle() == "SubmitOrder")
			setLocation(0 * getWidth(), 0 * getHeight());
		else if (getTitle() == "AcknowledgeOrder")
			setLocation(1 * getWidth(), 0 * getHeight());
		else if (getTitle() == "EnqueueOrder")
			setLocation(2 * getWidth(), 0 * getHeight());
		else if (getTitle() == "CheckRepo")
			setLocation(3 * getWidth(), 0 * getHeight());
		else if (getTitle() == "RejectOrder")
			setLocation(0 * getWidth(), 1 * getHeight() + 25);
		else if (getTitle() == "ServeOrder")
			setLocation(1 * getWidth(), 1 * getHeight() + 25);
		else if (getTitle() == "BookTransaction")
			setLocation(2 * getWidth(), 1 * getHeight() + 25);
		else if (getTitle() == "FulfillOrder")
			setLocation(3 * getWidth(), 1 * getHeight() + 25);
		else if (getTitle() == "FinishedOrderMonitor")
			setBounds(0, 2 * getHeight() + 25, 1200, 200);
	}

	/**
	 * Increments call counter and gets current window to the front.
	 */
	public synchronized void called() {
		callCount++;
		callCountLabel.setText(Integer.toString(callCount));
		toFront();
	}

	/**
	 * Appends a new log message to the log area.
	 * 
	 * @param log
	 *            the new log message
	 */
	public void log(String log) {
		logTextArea.append(log);
	}
}